import cn from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import { useForm } from 'react-hook-form';
import { joiResolver } from '@hookform/resolvers';
import { Link } from 'react-router-dom';
import { Warning32 as Warning } from '@carbon/icons-react';
import { gql, useQuery, useMutation } from '@apollo/client';

import { withRouter } from 'react-router';
import Textarea from '@kuiper-components/textarea';

import Dialog from '@kuiper-components/dialog';
import Input from '@kuiper-components/input';
import Button from '@kuiper-components/button';
import notification from '@kuiper-components/notification';

import { job2 as job } from '../../../../../common/validation';
import Form, { Field } from '../../../../components/Form';
import TargetInput from '../../../../components/TargetInput';
import s from './style.module.css';
import KDialog from '@knownsec/react-component/dist/Dialog'
import KForm from '@knownsec/react-component/dist/Form';
import KInput from '@knownsec/react-component/dist/Input';
import KSelect from '@knownsec/react-component/dist/Select';
import Tooltip from '@knownsec/react-component/dist/Tooltip';
import KTextarea from '@knownsec/react-component/dist/Textarea'
import Icon from '@knownsec/react-component/dist/Icon'
import w from '../style.module.css'
import moment from 'moment'

const USER_QUERY = gql`
	query {
		UserOne {
			_id
			disclaimerAgreeTime
		}
	}
`;

const AGREE_DISCLAIMER = gql`
	mutation {
		UpdateAgreeTime {
			_id
			disclaimerAgreeTime
		}
	}
`;
function CreateJob({
	className,
	children,
	onSubmit,
	uid,
	location,
	maxDomain,
	userInfo,
	isDialog,
	webData,
	assetType
}) {
	const search = new URLSearchParams(location.search);
	const openAndCreate = search.get('create-job');
	const plan_name = JSON.parse(sessionStorage.resD).plan_name;
	const isPlanTimeOut = moment().unix() > moment(sessionStorage.planTimeOut).unix()
	const [loading, setLoading] = React.useState(false);
	const [isAgreed, setIsAgreed] = React.useState(false);
	const [webRecord, setWebRecord] = React.useState(webData)
	const [webForm] = KForm.useForm()

	const [createDialogVisible, setCreateDialogVisible] = React.useState(
		!!openAndCreate
	);
	const [webCreateVisible, setWebCreateVisible] = React.useState(false)
	const [agreeVisible, setAgreeVisible] = React.useState(false);

	const form = useForm({
		defaultValues: {
			target: { protocol: 'https:', host: openAndCreate || '' },
		},
		// resolver: joiResolver(job),
		mode: 'onChange',
	});

	const [updateAgreeDate] = useMutation(AGREE_DISCLAIMER);
	const { data } = useQuery(USER_QUERY, {
		variables: { uid: userInfo?.uid },
	});
	const validatormap = (rule, value) => {
		if (rule.field === 'note') {
			if (!value || !value.trim()) {
				return Promise.reject('请输入资产名称');
			} else if (!(value.trim().replace(/[a-zA-Z0-9_\u4E00-\u9FA5]{1,50}/g, '').length === 0)) {
				return Promise.reject('名称格式错误，只能输入1～50个中文、英文字母、数字、下划线');
			} else {
				return Promise.resolve();
			}
			// eslint-disable-next-line prefer-promise-reject-errors
		} else {
			return Promise.resolve();
		}
	}
	const handleCloseModal = () => {
		if (assetType === 'web') {
			setWebRecord(webData)
			const protocol = [webData.target_url.split('//')[0] + '//']
			const url = webData.target_url.split('//')[1]
			setWebRecord({...webData, protocol, url})
			webForm.current.setFieldsValue({...webData, protocol, url});
			webForm.current.resetFields()
			setWebCreateVisible(false)
		} else {
			setCreateDialogVisible(false);
		}
	};
	const handleCloseAgreeModal = () => setAgreeVisible(false);

	const handleChildrenClick = () => {
		if (!userInfo?.identified) {
			notification.error({
				message: '当前还未进行实名认证，无法添加资产。',
				placement: 'top',
				style: { width: '22rem' },
			});
			return;
		}
		if (isPlanTimeOut) {
			notification.error({
				message: '当前套餐已过期，无法添加资产',
				placement: 'top',
			});
			return;
		}
		if (plan_name === '免费版' || plan_name === '源站安全检测') {
			notification.error({
				message: '当前账号未开通服务',
				placement: 'top',
			});
			return;
		}
		if (maxDomain?.total - maxDomain?.used <= 0) {
			notification.error({
				message: '当前套餐资产数已达到上限，无法继续添加。',
				placement: 'top',
			});
			return;
		}
		if (!data?.UserOne?.disclaimerAgreeTime) {
			setAgreeVisible(true);
			return;
		} else {
			if (isDialog) {
				if (assetType === 'web') {
					const protocol = [webData.target_url.split('//')[0] + '//']
					const url = webData.target_url.split('//')[1]
					webForm.current.setFieldsValue({...webData, protocol, url});
					setWebCreateVisible(true)
				} else {
					setCreateDialogVisible(true);
				}
			}
		}
		const onClick = children.props.onClick;
		if (onClick) onClick();
	};

	const handleAgree = () => {
		updateAgreeDate()
			.then(() => {
				setAgreeVisible(false);
				if (isDialog) {
					if (assetType === 'web') {
						setWebCreateVisible(true)
					} else {
						setCreateDialogVisible(true);
					}
				} else {
					const onClick = children.props.onClick;
					if (onClick) onClick();
				}
			})
			.catch(err => {
				notification.error({ message: err.message, placement: 'top' });
			});
	};

	const handleAgreeChange = val => {
		setIsAgreed(val);
	};

	const handleSubmit = async data => {
		setLoading(true);
		if (loading) return;
		const resp = await onSubmit(data);
		if (resp.code === 0) {
			sessionStorage.search = '?page=1&perPage=6';
			location.search = '';
			setCreateDialogVisible(false);
		} else {
			notification.error({
				type: 'error',
				message: resp.msg,
				placement: 'auto',
				style: { left: 'calc(50%)' },
			});
		}
		setLoading(false);
	};
	const [isCreate, setIsCreate] = React.useState(true)
	const webSubmit = () => {
		if (!isCreate) return false
		webForm.current.validateFields().then(async res => {
			if (res) {
				setIsCreate(false)
				const resp = await onSubmit({...res, target_url: res.protocol[0] + res.url });
				setIsCreate(true)
				if (resp.code === 0 || resp.message?.indexOf('失败') > -1) {
					setWebCreateVisible(false);
				}
			}
		})
	}
	return (
		<>
			{React.cloneElement(children, {
				...children.props,
				onClick: handleChildrenClick,
			})}
			<Dialog
				title="提示"
				visible={agreeVisible}
				wrapClassName={s.dialog}
				onClose={handleCloseAgreeModal}
				destroyOnClose={true}
			>
				<div className={s.agreeWapper}>
					<Warning className={s.warningIcon} />
					<div className={s.text}>
						<span>在添加资产前，请确认您已仔细阅读并同意</span> <br />
						<div>
							<Input
								type="checkbox"
								checked={isAgreed}
								onChange={handleAgreeChange}
							/>
							<Link to="/disclaimer" target="_blank">
								《知道创宇ScanV服务条款》
							</Link>
						</div>
					</div>
					<span>
						<Button className={s.quit} onClick={handleCloseAgreeModal}>
							取消
						</Button>
						{!isAgreed ? (
							<Button disabled={true}>已阅读并同意</Button>
						) : (
							<Button primary onClick={handleAgree}>
								已阅读并同意
							</Button>
						)}
					</span>
				</div>
			</Dialog>
			<Dialog
				title="添加资产"
				visible={createDialogVisible}
				wrapClassName={s.dialog}
				onClose={handleCloseModal}
				destroyOnClose={true}
				className={s.addDomain}
			>
				<Form
					className={cn(className, s.createJob)}
					form={form}
					onSubmit={handleSubmit}
				>
					<div className={s.inputContainer}>
						<Field
							required
							className={s.formField}
							label="资产名称"
							name="note"
							rules={[{ required: true, validator: validatormap }]}
							as={Input}
							placeholder="请输入资产名称"
							componentClassName={s.input}
						/>
						<Field
							required
							className={s.formField}
							label="资产地址"
							name="target"
							as={TargetInput}
							componentClassName={s.target}
							placeholder="请输入资产地址"
						/>
						<Field
							className={s.formField}
							label="源站IP"
							name="sourceIp"
							placeholder="请输入源站IP地址"
							as={Textarea}
							componentClassName={s.input}
						/>
					</div>
					<div className={s.btnContainer}>
						<Button className={s.btn} size="small" onClick={handleCloseModal}>
							取消
						</Button>
						{!form.formState.isValid ? (
							<Button
								className={s.btn}
								size="small"
								type="submit"
								disabled={true}
							>
								添加
							</Button>
						) : (
							<Button
								className={s.btn}
								primary
								size="small"
								type="submit"
								loading={loading}
							>
								添加
							</Button>
						)}
					</div>
				</Form>
			</Dialog>
			<KDialog visible={webCreateVisible}
				className={w.w550} title='添加资产'
				onhide={handleCloseModal} onsubmit={webSubmit}>
				<div className={cn(w.p20_0, w.createForm)}>
					<KForm ref={webForm}
						labelCol={{ span: 5 }}
						onValuesChange={(newItem, allValues) => {
							const val = recursion(newItem);
							function recursion(obj) {
								const obj_ = obj;
								const key = Object.keys(obj_);
								if (obj_[key] && typeof obj_[key] === 'object') {
									if ({}.propertyIsEnumerable.call(obj_[key], 'value')) {
										obj_[key] = obj_[key].value;
									} else if (
										{}.propertyIsEnumerable.call(obj_[key], 'selectedItem')
									) {
										if (obj_[key].selectedItem.length > 0) {
											if (obj_[key].selectedItem.length > 1) {
												obj_[key] = obj_[key].selectedItem.map(
													item => item.value
												);
											} else {
												obj_[key] = [obj_[key].selectedItem[0].value];
											}
										} else if (obj_[key].selectedItem.length === 0) {
											obj_[key] = [];
										}
									} else {
										obj_[key] = recursion(obj_[key]);
									}
								}
								return obj_;
							}
							webForm.current.setFieldsValue(val)
					}} wrapperCol={{ span: 18 }} initialValues={{ remember: true }}>
						<KForm.Item label="资产名称" name='note' rules={[{ required: true, validator: validatormap }]}>
							<KInput placeholder='请输入资产名称' />
						</KForm.Item>
						<KForm.Item label="资产地址" name='url' rules={[{ required: true, message: '请输入资产地址' }]}>
							<div className={cn(w.df, w.aic, w.bdt, 'error-box')}>
								<KForm.Item noStyle name='protocol'>
									<KSelect className={cn(w.w80, w.appendSelect)} option={[{ label:'http://', value: 'http://' }, { label:'https://', value: 'https://' }]} />
								</KForm.Item>
								<KForm.Item noStyle name='url'>
									<KInput className={w.flex1} placeholder='请输入资产地址' />
								</KForm.Item>
								<Tooltip overlay={
									(<div>
										协议+子域名/IPv4/IPv6+端口<br />
										示例：http://www.example.com:80<br />
										<span class="_tipSpan_7z5aq_29">http://[AD80:0000:0000:0000:ABAA:0000:00C2:0002]</span><br />
										<span class="_tipSpan_7z5aq_29">https://1.1.1.1</span><br />
									</div>)}
									placement='top'
									children={<Icon type='question' className={cn(w.cp, w.pa, w.r_20, w.fs20)} />}></Tooltip>
							</div>
						</KForm.Item>
						<KForm.Item label="源站IP" name='source_ip' validateStatus="warning" help='注：资产认证后，系统默认一周一次监测频率探测资产信息。'>
							<KTextarea rows={4} placeholder='请输入源站 IP 地址，若有多个 IP 地址可换行添加，多个源站 IP 算多个资产数量。' />
						</KForm.Item>
					</KForm>
					{/* <div className={cn(w.warningColor, w.pl40)}>注：资产认证后，系统默认一周一次监测频率探测资产信息。</div> */}
				</div>
			</KDialog>
		</>
	);
}

CreateJob.propTypes = {
	className: PropTypes.string,
	children: PropTypes.node.isRequired,
	onSubmit: PropTypes.func.isRequired,
	isDialog: PropTypes.bool,
	uid: PropTypes.string,
	location: PropTypes.shape({
		search: PropTypes.string,
	}),
	maxDomain: PropTypes.any,
	userInfo: PropTypes.shape({
		identified: PropTypes.bool,
		uid: PropTypes.string,
	}),
};
CreateJob.defaultProps = {
	className: s.createJob,
};

export default withRouter(CreateJob);
